home *** CD-ROM | disk | FTP | other *** search
/ Linux Cubed Series 3: Developer Tools / Linux Cubed Series 3 - Developer Tools.iso / utils / file / managers / mc-3.2 / mc-3 / mc-3.2.1 / src / boxes.c < prev    next >
Encoding:
C/C++ Source or Header  |  1996-05-17  |  20.2 KB  |  723 lines

  1. /* Some misc dialog boxes for the program.
  2.    
  3.    Copyright (C) 1994, 1995 the Free Software Foundation
  4.    
  5.    Authors: 1994, 1995 Miguel de Icaza
  6.             1995 Jakub Jelinek
  7.    
  8.    This program is free software; you can redistribute it and/or modify
  9.    it under the terms of the GNU General Public License as published by
  10.    the Free Software Foundation; either version 2 of the License, or
  11.    (at your option) any later version.
  12.    
  13.    This program is distributed in the hope that it will be useful,
  14.    but WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16.    GNU General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  21.  
  22. #include <config.h>
  23. #include "tty.h"
  24. #include <string.h>
  25. #include <stdio.h>
  26. #include <sys/types.h>
  27. #include <sys/stat.h>
  28. #include <sys/param.h>
  29. #include <malloc.h>
  30. #include "global.h"
  31. #include "mad.h"        /* The great mad */
  32. #include "util.h"        /* Required by panel.h */
  33. #include "win.h"        /* Our window tools */
  34. #include "color.h"        /* Color definitions */
  35. #include "dlg.h"        /* The nice dialog manager */
  36. #include "widget.h"        /* The widgets for the nice dialog manager */
  37. #include "dialog.h"        /* For do_refresh() */
  38. #include "wtools.h"
  39. #include "setup.h"        /* For profile_name */
  40. #include "profile.h"        /* Load/save user formats */
  41. #include "key.h"        /* XCTRL and ALT macros  */
  42. #include "command.h"        /* For cmdline */
  43. #include "dir.h"
  44. #include "panel.h"
  45. #include "boxes.h"
  46. #include "main.h"        /* For the confirm_* variables */
  47. #include "tree.h"
  48. #include "layout.h"        /* for get_nth_panel_name proto */
  49.  
  50. #define DISPLAY_X  48
  51. #define DISPLAY_Y  15
  52.  
  53. static Dlg_head *dd;
  54. static WInput *user;
  55. static WInput *status;
  56. static WCheck *check_status;
  57. static int current_mode;
  58.  
  59. #define VIEW_TYPES 4
  60.  
  61. static char *displays [VIEW_TYPES] = {
  62.     "Full file list", "Brief file list", "Long file list",
  63.     "User:"
  64. };
  65.  
  66. static char *formats_section = "Formats";
  67. static WRadio *my_radio;
  68.  
  69. static char *select_format (WInput *i)
  70. {
  71.     void     *profile_keys;
  72.     char     *key;
  73.     char     *value;
  74.     int      in_list;
  75.     Chooser  *my_user_list;
  76.     WListbox *p;
  77.  
  78.     my_user_list = new_chooser (DISPLAY_Y - 4, DISPLAY_X - 4, "Listing Mode...",
  79.                 CHOOSE_EDITABLE);
  80.     p = my_user_list->listbox;
  81.     p->allow_duplicates = 0;
  82.     
  83.     in_list = 0;
  84.     profile_keys = profile_init_iterator (formats_section, profile_name);
  85.     while (profile_keys){
  86.     profile_keys = profile_iterator_next (profile_keys, &key, &value);
  87.     listbox_add_item (p, 0, 0, value, 0);
  88.     }
  89.     listbox_add_item (my_user_list->listbox, 0, 0, i->buffer, 0);
  90.  
  91.     value = 0;
  92.     if (run_chooser (my_user_list) != B_CANCEL){
  93.     char     key [2];
  94.     int      count;
  95.     WLEntry  *e;
  96.  
  97.     key [1] = 0;
  98.     profile_clean_section (formats_section, profile_name);
  99.     e = p->top;
  100.     
  101.     for (count = 0 ; count < p->count; count++, e = e->next){
  102.         key [0] = 'A' + count - 1;
  103.         WritePrivateProfileString (formats_section, key, e->text,
  104.                        profile_name);
  105.     }
  106.     value = strdup (p->current->text);
  107.     }
  108.     
  109.     destroy_chooser (my_user_list);
  110.     return value;
  111. }
  112.  
  113. static int display_callback (struct Dlg_head *h, int id, int Msg)
  114. {
  115. #ifndef HAVE_X
  116.     char *text;
  117.     WInput *input;
  118.     
  119.     switch (Msg){
  120.     case DLG_DRAW:
  121.     attrset (REVERSE_COLOR);
  122.     dlg_erase (h);
  123.     draw_box (h, 1, 1, DISPLAY_Y-2, DISPLAY_X-2);
  124.  
  125.     attrset (COLOR_HOT_NORMAL);
  126.     dlg_move (h, 1, 2);
  127.     addstr (" Listing mode ");
  128.     attrset (COLOR_NORMAL);
  129.     dlg_move (h, 11, 3);
  130.     addstr ("On input lines, use C-v to get a listbox");
  131.     dlg_move (h, 12, 3);
  132.     addstr ("with other formats");
  133.     break;
  134.     
  135.     case DLG_KEY:
  136.     if (id == '\n'){
  137.         if ((WInput *) h->current->widget == user){
  138.         h->running = 0;
  139.         h->ret_value = B_USER + 6;
  140.         break;
  141.         }
  142.     
  143.         if ((WInput *) h->current->widget == status){
  144.         h->running = 0;
  145.         h->ret_value = B_USER + 7;
  146.         break;
  147.         }
  148.     }
  149.  
  150.     /* Handle the above C-v */
  151.     if (id == XCTRL('v') &&
  152.         ((WInput *) h->current->widget == user ||
  153.          (WInput *) h->current->widget == status)){
  154.         
  155.         input = (WInput *) h->current->widget;
  156.         
  157.         text = select_format (input);
  158.         if (text){
  159.         assign_text (input, text);
  160.         update_input (input);
  161.         }
  162.         return MSG_HANDLED;
  163.     }
  164.     
  165.     if ((id|0x20) == 'u' && h->current->widget != (Widget *) user
  166.         && h->current->widget != (Widget *) status){
  167.         my_radio->sel = 3;
  168.         dlg_select_widget (h, my_radio); /* force redraw */
  169.         dlg_select_widget (h, user);
  170.         return MSG_HANDLED;
  171.     }
  172.     }
  173. #endif    
  174.     return MSG_NOT_HANDLED;
  175. }
  176.  
  177. static void display_init (int radio_sel, char *init_text,
  178.               int _check_status, char *_status)
  179. {
  180.     dd = create_dlg (0, 0, DISPLAY_Y, DISPLAY_X, dialog_colors,
  181.              display_callback, "[Left and Right Menus]", "display",
  182.              DLG_CENTER);
  183.  
  184.     x_set_dialog_title (dd, "Listing mode");
  185.     tk_new_frame (dd, "b.");
  186.     add_widgetl (dd,
  187.         button_new (3, 32, B_CANCEL, "[ Cancel ]", 'c', 2, 0, 0),
  188.     XV_WLAY_RIGHTOF);
  189.  
  190.     add_widgetl (dd,
  191.     button_new (5, 32, B_ENTER,  "[[ Ok ]]", 'o', 3, 0, 0),
  192.      XV_WLAY_CENTERROW);
  193.     tk_end_frame ();
  194.  
  195.     tk_new_frame (dd, "m.");
  196.     status = input_new (9, 8, NORMAL_COLOR, 34, _status);
  197.     add_widgetl (dd, status, XV_WLAY_RIGHTDOWN);
  198.     input_set_point (status, 0);
  199.  
  200.     check_status = check_new (8, 4, _check_status, "user Mini status",'m', 5);
  201.     add_widgetl (dd, check_status, XV_WLAY_NEXTROW);
  202.     tk_end_frame ();
  203.     
  204.     tk_new_frame (dd, "r.");
  205.     user = input_new  (6, 14, NORMAL_COLOR, 29, init_text);
  206.     add_widgetl (dd, user, XV_WLAY_RIGHTDOWN);
  207.     input_set_point (user, 0);
  208.  
  209.     my_radio = radio_new (3, 4, VIEW_TYPES, displays, 1);
  210.     my_radio->sel = my_radio->pos = current_mode;
  211.     add_widgetl (dd, my_radio, XV_WLAY_BELOWCLOSE);
  212.     tk_end_frame ();
  213. }
  214.  
  215. int display_box (WPanel *panel, char **userp, char **minip, int *use_msformat,
  216.     int num)
  217. {
  218.     int result;
  219.     char *section = NULL;
  220.     char *p;
  221.  
  222.     if (!panel) {
  223.         p = get_nth_panel_name (num);
  224.         panel = (WPanel *) xmalloc (sizeof (WPanel), "temporary panel");
  225.         panel->list_type = list_full;
  226.         panel->user_format = strdup (DEFAULT_USER_FORMAT);
  227.         panel->user_mini_status = 0;
  228.         panel->mini_status_format = strdup (DEFAULT_USER_FORMAT);
  229.         section = copy_strings ("Temporal:", p, 0);
  230.         if (!profile_has_section (section, profile_name)) {
  231.             free (section);
  232.             section = strdup (p);
  233.         }
  234.         panel_load_setup (panel, section);
  235.         free (section);
  236.     }
  237.  
  238.     current_mode = panel->list_type;
  239.     display_init (panel->list_type, panel->user_format,
  240.           panel->user_mini_status, panel->mini_status_format);
  241.           
  242.     run_dlg (dd);
  243.  
  244.     result = -1;
  245.     
  246.     if (section) {
  247.         free (panel->user_format);
  248.         free (panel->mini_status_format);
  249.         free (panel);
  250.     }
  251.     
  252.     if (dd->ret_value != B_CANCEL){
  253.     result = my_radio->sel;
  254.     *userp = strdup (user->buffer);
  255.     *minip = strdup (status->buffer);
  256.     *use_msformat = check_status->state & C_BOOL;
  257.     }
  258.     destroy_dlg (dd);
  259.  
  260.     return result;
  261. }
  262.  
  263. #define SORT_X 40
  264. #define SORT_Y 14
  265.  
  266. static int sort_callback (struct Dlg_head *h, int id, int Msg)
  267. {
  268. #ifndef HAVE_X
  269.     switch (Msg){
  270.     case DLG_DRAW:
  271.     attrset (REVERSE_COLOR);
  272.     dlg_erase (h);
  273.     draw_box (h, 1, 1, SORT_Y-2, SORT_X-2);
  274.     attrset (COLOR_HOT_NORMAL);
  275.     dlg_move (h, 1, 2);
  276.     addstr (" Sort order ");
  277.     break;
  278.     }
  279. #endif
  280.     return 0;
  281. }
  282.  
  283. char *sort_orders_names [SORT_TYPES];
  284.  
  285. sortfn *sort_box (sortfn *sort_fn, int *reverse, int *case_sensitive)
  286. {
  287.     int i, r;
  288.     sortfn *result;
  289.     WCheck *c, *case_sense;
  290.  
  291.     result = 0;
  292.     
  293.     for (i = 0; i < SORT_TYPES; i++)
  294.     if ((sortfn *) (sort_orders [i].sort_fn) == sort_fn){
  295.         current_mode = i;
  296.         break;
  297.     }
  298.     
  299.     dd = create_dlg (0, 0, SORT_Y, SORT_X, dialog_colors, sort_callback,
  300.              "[Left and Right Menus]", "sort", DLG_CENTER);
  301.              
  302.     x_set_dialog_title (dd, "Sort order");
  303.  
  304.     tk_new_frame (dd, "b.");
  305.     add_widgetl (dd, button_new (6, 25, B_CANCEL, "[ Cancel ]", 'c', 2, 0, 0),
  306.         XV_WLAY_CENTERROW);
  307.  
  308.     add_widgetl (dd, button_new (8, 25, B_ENTER, "[ Ok ]", 'o', 2, 0, 0),
  309.     XV_WLAY_RIGHTDOWN);
  310.     tk_end_frame ();
  311.  
  312.     tk_new_frame (dd, "r.");
  313.     case_sense = check_new (4, 19, *case_sensitive, "case sensitive", 't', 10);
  314.     add_widgetl (dd, case_sense, XV_WLAY_RIGHTDOWN);
  315.     c = check_new (3, 19, *reverse, "Reverse", 'r', 0);
  316.     add_widgetl (dd, c, XV_WLAY_RIGHTDOWN);
  317.  
  318.     for (i = SORT_TYPES-1; i >= 0; i--){
  319.     sort_orders_names [i] = sort_orders [i].sort_name;
  320.     }
  321.     my_radio = radio_new (3, 3, SORT_TYPES, sort_orders_names, 1);
  322.     my_radio->sel = my_radio->pos = current_mode;
  323.     
  324.     add_widget (dd, my_radio);
  325.     tk_end_frame ();
  326.     run_dlg (dd);
  327.  
  328.     r = dd->ret_value;
  329.     if (r != B_CANCEL){
  330.     result = (sortfn *) sort_orders [my_radio->sel].sort_fn;
  331.     *reverse = c->state & C_BOOL;
  332.     *case_sensitive = case_sense->state & C_BOOL;
  333.     } else
  334.     result = sort_fn;
  335.     destroy_dlg (dd);
  336.  
  337.     return result;
  338. }
  339.  
  340. #define CONFY 10
  341. #define CONFX 46
  342.  
  343. static int my_delete;
  344. static int my_overwrite;
  345. static int my_exit;
  346.  
  347. static QuickWidget conf_widgets [] = {
  348. { quick_button,   4, 6, 4, CONFY, " [ Cancel ]",
  349.       'c', 3, B_CANCEL, 0, 0, XV_WLAY_RIGHTOF, "b." },
  350. { quick_button,   4, 6, 3, CONFY, " [ oK ] ",
  351.       'k', 4, B_ENTER, 0, 0, XV_WLAY_CENTERROW, "" },
  352.  
  353. { quick_checkbox, 1, 13, 5, CONFY, " confirm Exit ",
  354.       'e', 9, 0, &my_exit, 0, XV_WLAY_BELOWCLOSE, "c." },
  355. { quick_checkbox, 1, 13, 4, CONFY, " confirm Overwrite ",
  356.       'o', 9, 0, &my_overwrite, 0, XV_WLAY_BELOWCLOSE, "" },
  357. { quick_checkbox, 1, 13, 3, CONFY, " confirm Delete ",
  358.       'd', 9, 0, &my_delete, 0, XV_WLAY_BELOWCLOSE, "" },
  359. { 0,              0, 0, 0, 0, 0, 0, 0, 0, 0, XV_WLAY_DONTCARE }
  360. };
  361.  
  362. static QuickDialog confirmation =
  363. { CONFX, CONFY, -1, -1, " Confirmation ", "[Confirmation]", "quick_confirm",
  364.       conf_widgets };
  365.  
  366. void confirm_box ()
  367. {
  368.     my_delete    = confirm_delete;
  369.     my_overwrite = confirm_overwrite;
  370.     my_exit      = confirm_exit;
  371.     if (quick_dialog (&confirmation) != B_CANCEL){
  372.     confirm_delete    = my_delete;
  373.     confirm_overwrite = my_overwrite;
  374.     confirm_exit      = my_exit;
  375.     }
  376. }
  377.  
  378. #define DISPY 9
  379. #define DISPX 46
  380.  
  381. static int new_mode;
  382.  
  383. char *display_bits_str [] =
  384. { "Full 8 bits", "ISO 8859-1", "7 bits" };
  385.  
  386. static QuickWidget display_widgets [] = {
  387. { quick_button,   4,  6,    3, DISPY, " [ Ok ]",
  388.       'o', 3, B_ENTER, 0, 0, XV_WLAY_CENTERROW },
  389. { quick_button,   4,  6,    4, DISPY, " [ Cancel ]",
  390.       'c', 3, B_CANCEL, 0, 0, XV_WLAY_CENTERROW },
  391. { quick_radio,    4, DISPX, 3, DISPY, "", 3, 0, 0,
  392.       &new_mode, display_bits_str, XV_WLAY_BELOWCLOSE },
  393. { 0,              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, XV_WLAY_DONTCARE }
  394. };
  395.  
  396. static QuickDialog display_bits =
  397. { DISPX, DISPY, -1, -1, " Display bits ", "[Display bits]",
  398.   "dbits", display_widgets };
  399.  
  400. void display_bits_box ()
  401. {
  402.     int v;
  403.     int current_mode;
  404.  
  405.     if (full_eight_bits)
  406.     current_mode = 0;
  407.     else if (eight_bit_clean)
  408.     current_mode = 1;
  409.     else
  410.     current_mode = 2;
  411.     
  412.     display_widgets [2].value = current_mode;
  413.     v = quick_dialog (&display_bits);
  414.     if (v != B_ENTER)
  415.     return;
  416.  
  417.     eight_bit_clean = new_mode < 2;
  418.     full_eight_bits = new_mode == 0;
  419. #ifndef HAVE_SLANG
  420.     meta (stdscr, eight_bit_clean);
  421. #else
  422.     SLsmg_Display_Eight_Bit = full_eight_bits ? 128 : 160;
  423. #endif
  424. }
  425.  
  426. #define TREE_Y 20
  427. #define TREE_X 60
  428.  
  429. static int tree_colors [4];
  430.  
  431. static int tree_callback (struct Dlg_head *h, int id, int msg)
  432. {
  433.     switch (msg){
  434.  
  435.     case DLG_POST_KEY:
  436.     /* The enter key will be processed by the tree widget */
  437.     if (id == '\n' || ((WTree *)(h->current->widget))->done){
  438.         h->running = 0;
  439.         h->ret_value = B_ENTER;
  440.     }
  441.     return MSG_HANDLED;
  442.     
  443.     case DLG_DRAW:
  444.     attrset (REVERSE_COLOR);
  445.     dlg_erase (h);
  446.     draw_box (h, 1, 1, TREE_Y-2, TREE_X-2 );
  447.     attrset (COLOR_HOT_NORMAL);
  448.     dlg_move (h, 1, 2);
  449.     addstr (" Select directory ");
  450.     attrset (COLOR_NORMAL);
  451.  
  452.     }
  453.     return MSG_NOT_HANDLED;
  454. }
  455.  
  456. char *tree (char *current_dir)
  457. {
  458.     WTree    *mytree;
  459.     Dlg_head *dlg;
  460.     char     *val;
  461.  
  462.     tree_colors [3] = dialog_colors [0];
  463.     tree_colors [1] = dialog_colors [1];
  464.     
  465.     /* Create the components */
  466.     dlg = create_dlg (0, 0, TREE_Y, TREE_X, tree_colors,
  467.               tree_callback, "[Directory Tree]", "tree", DLG_CENTER);
  468.     mytree = tree_new (0, 2, 2, TREE_Y - 6, TREE_X - 5);
  469.     add_widget (dlg, mytree);
  470.  
  471.     run_dlg (dlg);
  472.     if (dlg->ret_value == B_ENTER)
  473.     val = strdup (mytree->selected_ptr->name);
  474.     else
  475.     val = 0;
  476.     
  477.     destroy_dlg (dlg);
  478.     return val;
  479. }
  480. #ifndef USE_VFS
  481. #ifdef USE_NETCODE
  482. #undef USE_NETCODE
  483. #endif
  484. #endif
  485.  
  486. #ifdef USE_VFS
  487.  
  488. #if defined(USE_NETCODE)
  489. #define VFSY 15
  490. #else
  491. #define VFSY 11
  492. #endif
  493.  
  494. #define VFSX 53
  495.  
  496. extern int vfs_timeout;
  497. extern int tar_gzipped_memlimit;
  498.  
  499. #if defined(USE_NETCODE)
  500. extern char *ftpfs_anonymous_passwd;
  501. extern char *ftpfs_proxy_host;
  502. extern ftpfs_directory_timeout;
  503. extern int use_netrc;
  504. #endif
  505.  
  506. int vfs_use_limit = 1;
  507. static char *ret_timeout;
  508. static char *ret_limit;
  509.  
  510. #if defined(USE_NETCODE)
  511. static char *ret_passwd;
  512. static char *ret_directory_timeout;
  513. static char *ret_ftp_proxy;
  514. static int ret_use_netrc;
  515. #endif
  516.  
  517. #if 0
  518. /* Not used currently */
  519. { quick_checkbox,  4, VFSX, 10, VFSY, "Use ~/.netrc",
  520.       'U', 0, 0, &ret_use_netrc, 0, XV_WLAY_BELOWCLOSE, "" },
  521. #endif
  522.  
  523. char *confvfs_str [] =
  524. { "Always to memory", "If size less than:" };
  525.  
  526. static QuickWidget confvfs_widgets [] = {
  527. { quick_button,   VFSX - 10 - 4,  VFSX,    VFSY - 3, VFSY, "[ Cancel ]",
  528.       'c', 2, B_CANCEL, 0, 0, XV_WLAY_RIGHTOF, "b." },
  529. { quick_button,   4, VFSX,    VFSY - 3, VFSY, "[ Ok ]",
  530.       'o', 4, B_ENTER, 0, 0, XV_WLAY_CENTERROW, "" },
  531. #if defined(USE_NETCODE)
  532. { quick_input,    23, VFSX, 10, VFSY, 0, 0, 10, 0, 0, &ret_ftp_proxy,
  533.       XV_WLAY_RIGHTDOWN, "" },
  534. { quick_label,     4, VFSX, 10, VFSY, "ftp proxy host:",
  535.       0, 0, 0, 0, 0, XV_WLAY_NEXTROW, ""},
  536. { quick_label,    46, VFSX, 9, VFSY, "sec",
  537.       0, 0, 0, 0, 0, XV_WLAY_RIGHTOF, "" },
  538. { quick_input,    35, VFSX, 9, VFSY, 0, 0, 10, 0, 0, &ret_directory_timeout,
  539.       XV_WLAY_RIGHTDOWN, "" },
  540. { quick_label,     4, VFSX, 9, VFSY, "ftpfs directory cache timeout:",
  541.       0, 0, 0, 0, 0, XV_WLAY_NEXTROW, ""},
  542. { quick_input,    28, VFSX, 8, VFSY, 0, 0, 21, 0, 0, &ret_passwd,
  543.       XV_WLAY_RIGHTDOWN, "" },
  544. { quick_label,     4, VFSX, 8, VFSY, "ftp anonymous password:",
  545.       0, 0, 0, 0, 0, XV_WLAY_NEXTROW, ""},
  546. #endif
  547. { quick_input,    26, VFSX, 6, VFSY, 0, 0, 10, 0, 0, &ret_limit, 
  548.       XV_WLAY_RIGHTDOWN, "l." },
  549. { quick_radio,    4, VFSX, 5, VFSY, "", 2, 0, 0,
  550.       &vfs_use_limit, confvfs_str, XV_WLAY_BELOWCLOSE, "" },
  551. { quick_label,    4,  VFSX, 4, VFSY, "Gzipped tar archive extract:", 
  552.       0, 0, 0, 0, 0, XV_WLAY_NEXTROW, "" },
  553. { quick_label,    46, VFSX, 3, VFSY, "sec",
  554.       0, 0, 0, 0, 0, XV_WLAY_RIGHTOF, "t." },
  555. { quick_input,    35, VFSX, 3, VFSY, 0, 0, 10, 0, 0, &ret_timeout, 
  556.       XV_WLAY_RIGHTOF, "" },
  557. { quick_label,    4,  VFSX, 3, VFSY, "Timeout for freeing VFSs:", 
  558.       0, 0, 0, 0, 0, XV_WLAY_BELOWCLOSE, "" },
  559. { 0,              0, 0, 0, 0, 0, 0, 0, 0, 0, 0, XV_WLAY_DONTCARE, 0 }
  560. };
  561.  
  562. static QuickDialog confvfs_dlg =
  563. { VFSX, VFSY, -1, -1, " Virtual File System Setting ", "[Virtual FS]", "quick_vfs", confvfs_widgets };
  564.  
  565. #if defined(USE_NETCODE)
  566. #define VFS_WIDGETBASE 7
  567. #else
  568. #define VFS_WIDGETBASE 0
  569. #endif
  570.  
  571. void configure_vfs ()
  572. {
  573.     char buffer1 [15], buffer2 [15];
  574. #if defined(USE_NETCODE)
  575.     char buffer3[15];
  576. #endif
  577.  
  578.     if (tar_gzipped_memlimit > -1) {
  579.         if (tar_gzipped_memlimit == 0)
  580.             strcpy (buffer1, "0 B");
  581.     else if ((tar_gzipped_memlimit % (1024*1024)) == 0) /* I.e. in M */
  582.         sprintf (buffer1, "%i MB", (int)(((unsigned)tar_gzipped_memlimit) >> 20));
  583.     else if ((tar_gzipped_memlimit % 1024) == 0) /* I.e. in K */
  584.         sprintf (buffer1, "%i KB", (int)(((unsigned)tar_gzipped_memlimit) >> 10));
  585.     else if ((tar_gzipped_memlimit % 1000) == 0)
  586.         sprintf (buffer1, "%i kB", (int)(tar_gzipped_memlimit / 1000));
  587.     else
  588.         sprintf (buffer1, "%i B", (int)tar_gzipped_memlimit);
  589.         confvfs_widgets [2 + VFS_WIDGETBASE].text = buffer1;
  590.     } else
  591.         confvfs_widgets [2 + VFS_WIDGETBASE].text = "5 MB";
  592.     sprintf (buffer2, "%i", vfs_timeout);
  593.     confvfs_widgets [6 + VFS_WIDGETBASE].text = buffer2;
  594.     confvfs_widgets [3 + VFS_WIDGETBASE].value = vfs_use_limit;
  595. #if defined(USE_NETCODE)
  596.     ret_use_netrc = use_netrc;
  597.     sprintf(buffer3, "%i", ftpfs_directory_timeout);
  598.     confvfs_widgets[5].text = buffer3;
  599.     confvfs_widgets[7].text = ftpfs_anonymous_passwd;
  600.     confvfs_widgets[2].text = ftpfs_proxy_host ? ftpfs_proxy_host : "";
  601. #endif
  602.  
  603.     if (quick_dialog (&confvfs_dlg) != B_CANCEL) {
  604.         char *p;
  605.         
  606.         vfs_timeout = atoi (ret_timeout);
  607.         free (ret_timeout);
  608.         if (vfs_timeout < 0 || vfs_timeout > 10000)
  609.             vfs_timeout = 10;
  610.         if (!vfs_use_limit)
  611.             tar_gzipped_memlimit = -1;
  612.         else {
  613.             tar_gzipped_memlimit = atoi (ret_limit);
  614.             if (tar_gzipped_memlimit < 0)
  615.                 tar_gzipped_memlimit = -1;
  616.             else {
  617.                 for (p = ret_limit; *p == ' ' || (*p >= '0' && *p <= '9'); p++);
  618.                 switch (*p) {
  619.         case 'm':
  620.         case 'M': tar_gzipped_memlimit <<= 20; break;
  621.         case 'K': tar_gzipped_memlimit <<= 10; break;
  622.         case 'k': tar_gzipped_memlimit *= 1000; break;
  623.                 }
  624.             }
  625.         }
  626.         free (ret_limit);
  627. #if defined(USE_NETCODE)
  628.     free(ftpfs_anonymous_passwd);
  629.     ftpfs_anonymous_passwd = ret_passwd;
  630.     if (ftpfs_proxy_host)
  631.         free(ftpfs_proxy_host);
  632.     ftpfs_proxy_host = ret_ftp_proxy;
  633.     ftpfs_directory_timeout = atoi(ret_directory_timeout);
  634.     use_netrc = ret_use_netrc;
  635.     free(ret_directory_timeout);
  636. #endif
  637.     }
  638. }
  639.  
  640. #endif
  641.  
  642. char *cd_dialog (void)
  643. {
  644.     QuickDialog Quick_input;
  645.     QuickWidget quick_widgets [] = {
  646. #ifdef HAVE_TK
  647. #define INPUT_INDEX 2
  648.     { quick_button, 0, 1, 0, 1, "Cancel", 'c', 0, B_CANCEL, 0, 0,
  649.       XV_WLAY_DONTCARE, "b." },
  650.     { quick_button, 0, 1, 0, 1, "Ok", 'o', 0, B_ENTER, 0, 0,
  651.       XV_WLAY_DONTCARE, "" },
  652. #else
  653. #define INPUT_INDEX 0
  654. #endif
  655.     { quick_input,  8, 80, 5, 0, 0, 0, 50, 0, 0, 0, XV_WLAY_RIGHTOF, 0 },
  656.     { quick_label,  3, 80, 2, 0, 0, 0, 0, 0, 0, 0, XV_WLAY_DONTCARE, 0 },
  657.     { 0 } };
  658.     
  659.     char *my_str;
  660.     
  661.     Quick_input.xlen  = 57;
  662.     Quick_input.title = "Quick cd";
  663.     Quick_input.help  = "[Quick cd]";
  664.     Quick_input.class = "quick_input";
  665.     quick_widgets [INPUT_INDEX].text = "";
  666.     quick_widgets [INPUT_INDEX].value = 2; /* want cd like completion */
  667.     quick_widgets [INPUT_INDEX+1].text = "cd";
  668.     quick_widgets [INPUT_INDEX+1].y_divisions =
  669.     quick_widgets [INPUT_INDEX].y_divisions =
  670.             Quick_input.ylen  = 5;
  671.     Quick_input.xpos = 2;
  672.     Quick_input.ypos = ((Widget *) cmdline)->y - Quick_input.ylen;
  673.     quick_widgets [INPUT_INDEX].relative_y = 2;
  674.     quick_widgets [INPUT_INDEX].str_result = &my_str;
  675.     
  676.     Quick_input.widgets = quick_widgets;
  677.     if (quick_dialog (&Quick_input) != B_CANCEL){
  678.     return *(quick_widgets [INPUT_INDEX].str_result);
  679.     } else
  680.     return 0;
  681. }
  682.  
  683. void symlink_dialog (char *existing, char *new, char **ret_existing, 
  684.     char **ret_new)
  685. {
  686.     QuickDialog Quick_input;
  687.     QuickWidget quick_widgets [] = {
  688. #ifdef HAVE_TK
  689. #define INPUT_INDEX 2
  690.     { quick_button, 0, 1, 0, 1, "Cancel", 'c', 0, B_CANCEL, 0, 0,
  691.       XV_WLAY_DONTCARE, "b." },
  692.     { quick_button, 0, 1, 0, 1, "Ok", 'o', 0, B_ENTER, 0, 0,
  693.       XV_WLAY_DONTCARE, "" },
  694. #else
  695. #define INPUT_INDEX 0
  696. #endif
  697.     { quick_input,  4, 80, 5, 8, 0, 0, 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, 0 },
  698.     { quick_label,  4, 80, 4, 8, 0, 0, 0, 0, 0, 0, XV_WLAY_BELOWOF, 0 },
  699.     { quick_input,  4, 80, 3, 8, 0, 0, 58, 0, 0, 0, XV_WLAY_BELOWCLOSE, 0 },
  700.     { quick_label,  4, 80, 2, 8, 0, 0, 0, 0, 0, 0, XV_WLAY_DONTCARE, 0 },
  701.     { 0 } };
  702.     
  703.     Quick_input.xlen  = 64;
  704.     Quick_input.ylen  = 8;
  705.     Quick_input.title = "Symbolic link";
  706.     Quick_input.help  = "[File Menu]";
  707.     Quick_input.class = "quick_symlink";
  708.     quick_widgets [INPUT_INDEX].text = new;
  709.     quick_widgets [INPUT_INDEX+1].text = "Symbolic link filename:";
  710.     quick_widgets [INPUT_INDEX+2].text = existing;
  711.     quick_widgets [INPUT_INDEX+3].text = "Existing filename (filename symlink will point to):";
  712.     Quick_input.xpos = -1;
  713.     quick_widgets [INPUT_INDEX].str_result = ret_new;
  714.     quick_widgets [INPUT_INDEX+2].str_result = ret_existing;
  715.     
  716.     Quick_input.widgets = quick_widgets;
  717.     if (quick_dialog (&Quick_input) == B_CANCEL){
  718.         *ret_new = NULL;
  719.         *ret_existing = NULL;
  720.     }
  721. }
  722.  
  723.